/// <reference types="node" />
const childProcess = require("child_process");
const fs = require("fs");
const toml = require("@iarna/toml");

/** @type {{name: string}} */
const config = /** @type {any} */ (
  toml.parse(fs.readFileSync("wrangler.0.toml").toString())
);

/**
 * @param  {...string} args
 */
function wrangler(...args) {
  const command = ["npx", "wrangler", ...args, "-c", "wrangler.0.toml"] //
    .join(" ");
  const returns = childProcess.spawnSync(command, { shell: true });
  const stderr = returns.stderr.toString();
  if (stderr.length !== 0) {
    throw new Error(stderr.trimEnd());
  }
  return returns.stdout.toString();
}

function authenticated() {
  return wrangler("whoami").search("You are not authenticated.") === -1;
}

function login() {
  wrangler("login");
}

/**
 * @returns {Record<string, {id: string, supportsUrlEncoding: boolean} | undefined>}}
 */
function listKVNamespaces() {
  /** @type {{id: string, title: string, supports_url_encoding: boolean}[]} */
  const namespaces = JSON.parse(wrangler("kv:namespace", "list"));
  return Object.fromEntries(
    namespaces.map((namespace) => [
      namespace.title,
      {
        id: namespace.id,
        supportsUrlEncoding: namespace.supports_url_encoding,
      },
    ])
  );
}

/**
 * @param {string} name
 * @param {boolean} preview
 */
function title(name, preview) {
  return `${config.name}-${name}${preview ? "_preview" : ""}`;
}

/**
 * @param {string} name
 * @param {boolean} preview
 */
function createKVNamespace(name, preview) {
  const command = ["kv:namespace", "create", name];
  if (preview) {
    command.push("--preview");
  }
  const stdout = wrangler(...command);
  const pattern = preview
    ? `\{ binding = "${name}", preview_id = "([^"]{32})" \}`
    : `\{ binding = "${name}", id = "([^"]{32})" \}`;
  const result = stdout.match(new RegExp(pattern));
  // @ts-ignore
  return result[1];
}

module.exports = {
  wrangler,
  config,
  authenticated,
  login,
  listKVNamespaces,
  title,
  createKVNamespace,
};
